package com.donleo.stmg.relation.service.impl;

import com.donleo.stmg.common.api.CommonResult;
import com.donleo.stmg.relation.mapper.UserLoginRecordMapper;
import com.donleo.stmg.relation.model.UserLoginRecord;
import com.donleo.stmg.relation.service.EsUserLoginRecordService;
import com.donleo.stmg.relation.vo.EsUserLoginRecordVo;
import com.donleo.stmg.repository.EsUserLoginRecordRepository;
import com.donleo.stmg.utils.DateUtil;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.matchQuery;

/**
 * @author liangd
 * date 2021-01-03 20:21
 * code
 */
@Service
public class EsUserLoginRecordServiceImpl implements EsUserLoginRecordService {

    @Autowired
    private EsUserLoginRecordRepository esUserLoginRecordRepository;

    @Autowired
    private UserLoginRecordMapper userLoginRecordMapper;

    @Autowired
    private ElasticsearchRestTemplate restTemplate;


    @Override
    public int importAll() {

        List<UserLoginRecord> uList = userLoginRecordMapper.selectList(null);
        //将list里面的数据浅拷贝到es中
        List<EsUserLoginRecordVo> collect = uList.stream().map(userLoginRecord -> {
            EsUserLoginRecordVo esUserLoginRecordVo = new EsUserLoginRecordVo();
            BeanUtils.copyProperties(userLoginRecord, esUserLoginRecordVo);
            esUserLoginRecordVo.setLoginTime(DateUtil.addTime(esUserLoginRecordVo.getLoginTime()));
            return esUserLoginRecordVo;
        }).collect(Collectors.toList());
        esUserLoginRecordRepository.saveAll(collect);
        return uList.size();
    }

    @Override
    public void delete(Integer id) {
        EsUserLoginRecordVo recordVo = new EsUserLoginRecordVo();
        recordVo.setId(id);
        esUserLoginRecordRepository.delete(recordVo);
    }

    @Override
    public Page<EsUserLoginRecordVo> search(String keyword, Integer pageNum, Integer pageSize) {
        NativeSearchQuery userName = new NativeSearchQueryBuilder()
                .withQuery(matchQuery("username", keyword)).build();
        return esUserLoginRecordRepository.search(userName);
    }

    @Override
    public SearchHits searchHit(String keyword) {
        Query query = new NativeSearchQueryBuilder()
                .withQuery(matchQuery("username", keyword))
                .withHighlightFields(
                        new HighlightBuilder.Field("username")
                                .preTags("<font style='color:red'>").postTags("</font>")
                ).build();
        return restTemplate.search(query, EsUserLoginRecordVo.class);
    }

    /**
     *
     * @param userName  高亮显示的字段
     * @return
     */
    @Override
    public CommonResult transferSearchHit(String userName) {
        Query query = new NativeSearchQueryBuilder()
                .withQuery(matchQuery("username", userName))
                .withHighlightFields(
                        new HighlightBuilder.Field("username")
                                .preTags("<font style='color:red'>").postTags("</font>")
                ).build();
        SearchHits<EsUserLoginRecordVo> search = restTemplate.search(query, EsUserLoginRecordVo.class);
        List<EsUserLoginRecordVo> collect = tansferSearchHitToEsRole(search);

        return CommonResult.success(collect);
    }

    /**
     * 1、获取searchHits
     * 2、获取content
     * 3、获取highlightFields
     * 4、利用反射将highlightFields的字段值赋值给context的字段值
     * 5、用collect将map对象收集起来转换为集合
     * @param search
     * @return
     */
    private List<EsUserLoginRecordVo> tansferSearchHitToEsRole(SearchHits<EsUserLoginRecordVo> search){
        List<SearchHit<EsUserLoginRecordVo>> searchHits = search.getSearchHits();
        List<EsUserLoginRecordVo> collect = searchHits.stream().map(searchHit -> {
            EsUserLoginRecordVo content = searchHit.getContent();
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            highlightFields.forEach((k, v) -> {
                StringBuilder temp = new StringBuilder();
                for (String value : v) {
                    temp.append(value);
                }
                String s = temp.toString();
                try {
                    Field keyField = EsUserLoginRecordVo.class.getDeclaredField(k);
                    keyField.setAccessible(true);
                    keyField.set(content, s);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            return content;
        }).collect(Collectors.toList());
        return collect;
    }
}
